L’objectiu d’aquesta anàlisi és comparar diferents models predictius per poder determinar la polaritat d’un Tweet. En concret ens interessarà saber si un determinat Tweet és positiu o no partint de les paraules que el componen. La variable dependent a predir serà una variable qualitativa (POSITIU) i que es tractarà com un factor de dos possibles valors (V / F). Les variables independents seran el conjunt de paraules que formen els diferents Tweets que utilitzarem. Indicar que els Tweets que s’analitzarem seran en castellà i que en aquest idioma no existeixen paquets en R que puguin ajudar-nos a obtenir la polaritat d’un Tweet.
Twitter s’ha convertit en una xarxa social molt important i d’un gran volum d’informació on l’anàlisi dels textos dels Tweets que s’escriuen pot oferir-nos una informació d’un gran valor. Obtenir la polaritat (positiu / negatiu) o els sentiments dels Tweets és una tasca complexa a causa de les característiques del llenguatge natural i de la pròpia forma d’un Tweet: un llenguatge dens de 280 caràcters com a màxim, que pot contenir abreviatures, paraules en argot, ironies , hashtags o mencions a altres usuaris entre altres elements. Totes aquestes característiques dificulten un correcte anàlisi i a causa d’això l’anàlisi de sentiment del llenguatge natural és un tema de molta actualitat.
En aquest anàlisi compararem diferents models per escollir aquell que ens ofereixi uns resultats de predicció millors, és a dir uns errors de classificació de Tweets positius menors. L’algoritme resultant d’aquesta comparativa s’emprarà en el panell de control desenvolupat i que formarà l’inspector sanitari d’aquest TFM.
En aquest apartat estudiarem la naturalesa de les dades a tractar per poder extreure les característiques que ens permetin crear els models predictius.
El nostre conjunt de dades està format per un total de 11.290 Tweets que ja han estat categoritzats. Els nivells de classificació utilitzats són el següents:
Els fitxers emprats corresponen al taller TASS i, prèvia sol·licitud d’accés a la SEPLN, s’han obtingut de la següent adreça. TASS.
En concret els fitxers emprats són els següents:
- general-train-tagged
- intertass-train-tagged
- intertaas-development-tagged
- socialtv-train-tagged
- stompol-train-tagged
Són fitxers amb Tweets de diferents àmbits: general, vida social, política i categoritzats d’un manera subjectiva pel que podríem trobar Tweetss que per a una persona fossin positius i per a una altra negatius.
El primer pas a realitzar és fusionar tots els fitxers a tractar i seleccionar les columnes que ens interessen per poder realitzar els nostres models predictius. En concret ens interessa la columna “TEXT” i la columna “POLARITAT”. A continuació es pot veure l’estructura del DataFrame resultant.
Es pot veure també el Text de diversos Tweets i podem fixar-nos com ja podíem imaginar que el text pot tenir elements que són Hashtags (#), mencions a altres usuaris (@) o altres elements propis de Twitter com és la indicació per indicar que un Tweet és un ReTweet d’un altre (RT). Per centrar-nos només en el contingut propi del tuit i perquè aquests elements no puguin interferir en les prediccions dels nostres models eliminarem aquests elements. Aquest procés es realitzarà a posteriori, primer anem a analitzar els Tweets originals sense modificar.
## 'data.frame': 11290 obs. of 2 variables:
## $ Texto : chr "Salgo de #VeoTV , que día más largoooooo..." "@PauladeLasHeras No te libraras de ayudar me/nos. Besos y gracias" "@marodriguezb Gracias MAR" "Off pensando en el regalito Sinde, la que se va de la SGAE cuando se van sus corruptos. Intento no sacar conclu"| __truncated__ ...
## $ Polaridad: chr "NONE" "NEU" "P" "N+" ...
La distribució dels Tweets segons la seva polaritat és la següent:
Per simplificar fusionarem Tweets “Molt Positius” i “Positius” i els “Molt Negatius” i “Negatius” per obtenir un total de 4 nivells de polaritat. La nova distribució és la següent. Podem veure com el nombre de Tweets “Positius” és lleugerament superior al nombre de Tweets “Negatius” el que ens indica una distrubición bastant equitativa.
Volem veure a continuació la distribució del contingut de les paraules que formen Tweets organitzat segons la polaritat del Tweet al qual pertanyen. Per això construirem el següent wordcloud.
Podem veure com el wordcloud ens il·lustra d’una manera gràfica com paraules com “gracias”, “feliz”, “bien” o “mejor” estan classificades en Tweets Positius i com a paraules com “violencia”, “mala”, “deficit” o “impuestos” estan classificades com a pertanyents a Tweets Negatius. Això ens indica que una predicció basada en el conjunt de paraules que formen un Tweet pot oferir bons resultats.
Ens fixem també, que ens trobem paraules que no ens apartaran valor per a la predicció com ara: “http”, números, o preposicions o articles. Com ja hem comentat dedicarem un apartat d’aquesta anàlisi a la neteja dels tuits per treballar només amb aquella informació que ens pugui aportar valor.
A continuació i atès que volem predir aquells tuits que siguin positius crearem la nostra variable dependent generant una nova variable factor d’aquells Tweets que siguin positius.
## 'data.frame': 11290 obs. of 3 variables:
## $ Texto : chr "Salgo de #VeoTV , que día más largoooooo..." "@PauladeLasHeras No te libraras de ayudar me/nos. Besos y gracias" "@marodriguezb Gracias MAR" "Off pensando en el regalito Sinde, la que se va de la SGAE cuando se van sus corruptos. Intento no sacar conclu"| __truncated__ ...
## $ Polaridad: Factor w/ 4 levels "N","NEU","NONE",..: 3 2 4 1 4 3 4 3 4 4 ...
## $ Positivo : Factor w/ 2 levels "FALSE","TRUE": 1 1 2 1 2 1 2 1 2 2 ...
A continuació anem a dividir les nostres dades en Training, Validació i Test. Fem aquesta distribució per poder entrenar els nostres models en el conjunt de Training, validar-los en el conjunt de Validació i un cop seleccionat el millor model, obtenir el resultat final sobre el conjunt de test. La divisió que realitzarem del total dels tuits serà la següent:
## [1] 6775 3
## [1] 2258 3
## [1] 2257 3
En termes de processament de llenguatge, un Corpus és un conjunt gran i estructurat de textos. S’utilitzen per a realitzar anàlisis estadístics, verificar ocurrències o validar regles lingüístiques dins d’un àmbit lingüístic específic. En el nostre cas particular, estem parlant de la col·lecció de fragments de text que formen el conjunt de tots els Tweets.
Treballar amb un Corpus implica l’ús de tècniques de processament de llenguatge natural i com a tal l’extracció de característiques per determinar com influeixen les associacions de paraules en la polaritat d’un Tweet. Aquesta tasca pot esser complexa i segueix sent avui en dia un àmbit d’estudi molt actual.
En aquesta anàlisi i atès que l’objectiu és més aviat la comparació de models predictius que una extracció de característiques òptima utilitzarem el concepte de “Borsa de Paraules.” Els requisits d’un classificador de “Borsa de Paraules” “són mínims ja que només necessitem comptar les paraules, de manera que el procés es redueix a fer una certa simplificació i unificació dels termes i després contar-los.
Llavors, serà necessari processar els textos que formen els nostres Tweets per poder quedar-nos amb la informació que aporta valor al Tweet. Posteriorment crearem un corpus per poder extreure les freqüències de les paraules.
Per exemple, el contingut dels dos primers Tweets o documents es veu així.
## [1] "Salgo de #VeoTV , que día más largoooooo..."
## [1] "@PauladeLasHeras No te libraras de ayudar me/nos. Besos y gracias"
Per poder emprar el Corpus correctament necessitem simplificar i transformar el seu contingut a un format estàndard per a tots els Tweets. Els processos de neteja i estandardització que s’han realitzat han estat els següents:
Un cop realitzat aquest procés les dues primeres entrades es veuen així:
## [1] "salgo día largoooooo"
## [1] "no libraras ayudar menos besos gracias"
Per trobar les característiques del nostre classificador, posarem aquest Corpus a la forma d’una matriu de documents (DocumentTermMatrix). Una matriu de documents és una matriu numèrica que conté una columna per a cada paraula diferent en tot el nostre Corpus i una fila per a cada document. Una cel·la donada és igual a la freqüència en un document per a un terme donat.
D’aquesta manera fem servir les nostres entrades de text per construir freqüències de termes. Acabem amb les mateixes entrades en el nostre conjunt de dades però, en lloc de tenir-les definides per un text complet, ara estan definides per una sèrie de recomptes de les paraules més freqüents en tot el nostre corpus. Aquestes seran les característiques que utilitzarem per entrenar al nostre classificador.
## <<DocumentTermMatrix (documents: 9033, terms: 18528)>>
## Non-/sparse entries: 65034/167298390
## Sparsity : 100%
## Maximal term length: 52
## Weighting : term frequency (tf)
Un exemple de mostra de la nostra matriu és el següent:
## <<DocumentTermMatrix (documents: 50, terms: 10)>>
## Non-/sparse entries: 16/484
## Sparsity : 97%
## Maximal term length: 12
## Weighting : term frequency (tf)
## Sample :
## Terms
## Docs ayudar besos conclusiones día gracias largoooooo libraras mar menos
## 1 0 0 0 1 0 1 0 0 0
## 13 0 0 0 0 2 0 0 0 0
## 2 1 1 0 0 1 0 1 0 1
## 27 0 0 0 0 0 0 0 0 1
## 3 0 0 0 0 1 0 0 1 0
## 38 0 0 0 0 0 0 0 0 1
## 4 0 0 1 0 0 0 0 0 0
## 5 0 0 0 0 0 0 0 0 0
## 50 0 0 0 1 0 0 0 0 0
## 8 0 0 0 2 0 0 0 0 0
## Terms
## Docs salgo
## 1 1
## 13 0
## 2 0
## 27 0
## 3 0
## 38 0
## 4 0
## 5 0
## 50 0
## 8 0
Atès que la matriu conté un total de 18.528 termes diferents i un valor de sparsity de 100% estudiarem les freqüències dels termes i només ens quedarem amb aquells més freqüents per descartar els menys freqüents i que no ens aporten valor. A continuació podem veure la distribució de freqüències de termes en la nostra matriu.
## (Intercept) x
## 8.1149688 -0.8591446
Com era d’esperar hi ha pocs termes amb una alta freqüència i molts termes amb freqüències baixes. Obtindrem a continuació una llista dels 20 termes més freqüents.
Per obtenir una representació més àmplia dels termes més freqüents generem a continuació un WordCloud on la mida i el color dels termes ens indica la quantitat d’aparicions en els textos.
Si l’objtetiu d’aquesta comparativa fos optimitzar l’extracció de característiques del llenguatge natural dels Tweets per poder optimitzar també el nostre classificador podríem continuar amb l’anàlisi de la informació i incorporar al model no només paraules independents unes de les altres (unigramas) sinó també de quina manera influeix la combinació de dues o més paraules en la predicció de la polaritat (bigrames, n-grams). Un exemple és la recerca d’associacions entre les paraules “madrid” o “gràcies”.
findAssocs(tdm, "madrid", 0.2)
## $madrid
## real hala ¡hala
## 0.47 0.42 0.21
findAssocs(tdm, "gracias", 0.2)
## $gracias
## muchas
## 0.21
Incorporant aquesta informació al nostre model podríem optimitzar les prediccions dels nostres algoritmes ja que consideraríem combinacions de paraules en lloc de només paraules independents. Atès que no es tracta de l’objectiu d’aquesta comparativa ens centrarem en la generació dels models predictius per paraules independents.
Atès que alguns termes són més importants que d’altres, volem eliminar aquells que no ho són tant. Podem fer servir per això la funció removeSparseTerms del paquet “tm” on indicam la matriu i un nombre que proporciona la dispersió màxima permesa per a un terme en el nostre corpus.
Per exemple, si volem termes que apareguin en almenys l’1% dels documents, podem fer el següent.
Acabem amb només 1117 termes.
Ara volem convertir aquesta matriu en dos DataFrames diferents, un training i un altre de validació que puguem utilitzar per entrenar i validar els nostres models.
D’aquesta manera obtenim un DataFrame per als nostres valors d’entrenament format per 6775 mostres i 1118 columnes. 1117 variables independents i una variable dependent.
## [1] 6775 1117
De la mateixa manera pel nostre conjunt de validació.
## [1] 2258 1117
En aquest apartat estudiarem i compararem els diferents models de classificació que ens permetran obtenir prediccions sobre la polaritat d’un Tweet concret. Per poder comparar-los ens basarem en l’error de classificació que haurem obtingut després d’entrenar els nostres models en el conjunt de dades de Training i realitzar les prediccions en el conjunt de dades de Validació realitzant Validació Creuada per a aquells models que necessiten ajustar alguns paràmetres. Guardarem el valor obtingut per a cada un dels models i finalment els comparem per realitzar les prediccions en les dades de test.
Segons la naturalesa de les dades podria succeir que alhora d’intentar predir Tweets positius, la gran majoria dels nostres Tweets ja fossin classificats com a positius fet que faria que el nostre classificador no fos realista. Hem vist com la proporció entre Tweets positius i negatius era més o menys equitativa però tot i així necessitem saber l’error mínim de classificació per saber a partir de quines prediccions de classificació dels nostres models s’obtenen millors valors que el simple fet d’obtenir-los a l’atzar.
A continuació obtindrem l’error mínim de classificació per sobre del qual en aplicar els algoritmes d’aquesta comparativa podrem dir que obtenim una millor classificació que simplement generar un valor aleatori.
##
## FALSE TRUE
## 6996 4294
## FALSE
## 0.6196634
L’algoritme de classificació de regressió logística ens permet predir la probabilitat d’una variable dependent categòrica sent el resultat una variable binària que conté valors de 0 o 1. Atès que volem predir si un Tweet serà positiu o no (2 classes) pot ser que aquest mètode ens ofereixi bons resultats. Esperem que en el nostre cas també pugui explicar la relació entre la variable dependent i les variables independents.
##
## Call:
## glm(formula = Positivo ~ ., family = "binomial", data = train_data_words_df)
##
## Deviance Residuals:
## Min 1Q Median 3Q Max
## -2.4641 -0.8861 -0.7730 1.1826 2.2068
##
## Coefficients:
## Estimate Std. Error z value Pr(>|z|)
## (Intercept) -0.7323783 0.0366607 -19.977 < 2e-16 ***
## día 0.4605397 0.1653209 2.786 0.005341 **
## gracias 2.3058155 0.1910087 12.072 < 2e-16 ***
## menos 0.0694611 0.2145064 0.324 0.746075
## hoy 0.2596312 0.1217492 2.133 0.032965 *
## madrid 0.7408895 0.1222590 6.060 1.36e-09 ***
## grande 1.7651917 0.2935412 6.013 1.82e-09 ***
## ser 0.2671174 0.1851876 1.442 0.149185
## congreso 0.1258858 0.2400809 0.524 0.600037
## días -0.0670074 0.2364503 -0.283 0.776879
## gran 1.1292641 0.1987087 5.683 1.32e-08 ***
## ahora -0.3084953 0.1638956 -1.882 0.059800 .
## mundo 0.0830176 0.2840656 0.292 0.770097
## sin -0.6122986 0.1871093 -3.272 0.001066 **
## puede -0.4800905 0.2503317 -1.918 0.055134 .
## siempre 0.6988010 0.2290179 3.051 0.002279 **
## copa 0.0827461 0.2053607 0.403 0.686999
## españa -0.0718947 0.1823331 -0.394 0.693357
## ver 0.2994785 0.1764110 1.698 0.089580 .
## noche 0.1393706 0.2284307 0.610 0.541781
## dos -0.0005818 0.2281710 -0.003 0.997966
## hace -0.2542465 0.2151294 -1.182 0.237273
## así 0.0728419 0.2227494 0.327 0.743658
## nuevo 0.7814632 0.2398250 3.258 0.001120 **
## vía -0.0081445 0.2050206 -0.040 0.968312
## años 0.2194617 0.2247444 0.976 0.328820
## nada -0.1975717 0.2150998 -0.919 0.358351
## vez -0.3147683 0.2542632 -1.238 0.215730
## bien 0.9488766 0.1910591 4.966 6.82e-07 ***
## bueno 0.7987374 0.2058748 3.880 0.000105 ***
## tan -0.3227490 0.2449885 -1.317 0.187703
## buenos 0.8927860 0.2706529 3.299 0.000972 ***
## gobierno -0.0620990 0.1747777 -0.355 0.722363
## solo -0.1794140 0.2228681 -0.805 0.420806
## rajoy -0.3966623 0.1754378 -2.261 0.023760 *
## final -0.3151125 0.2555826 -1.233 0.217606
## mas 0.4686867 0.1689887 2.773 0.005546 **
## mejor 1.3828335 0.1886274 7.331 2.28e-13 ***
## rey 0.3128600 0.2423094 1.291 0.196649
## vamos 0.8559184 0.2088448 4.098 4.16e-05 ***
## equipo 1.1773687 0.2810960 4.188 2.81e-05 ***
## partido 0.2821810 0.1995863 1.414 0.157412
## año 0.3359430 0.2100643 1.599 0.109767
## pues -0.2130868 0.2508325 -0.850 0.395593
## cosas -0.5001837 0.2941208 -1.701 0.089017 .
## feliz 1.9344542 0.3504378 5.520 3.39e-08 ***
## barcelona -1.0691233 0.2576430 -4.150 3.33e-05 ***
## real -0.0434429 0.1890871 -0.230 0.818285
## barça -0.5495611 0.2107012 -2.608 0.009101 **
## rubalcaba 0.0134573 0.2593373 0.052 0.958616
## aquí 0.5461401 0.2242121 2.436 0.014858 *
## psoe -0.6724988 0.2415979 -2.784 0.005377 **
## mañana 0.2087931 0.1707710 1.223 0.221462
## dice -0.7798370 0.2531734 -3.080 0.002068 **
## hacer -0.1686270 0.2201327 -0.766 0.443662
## portada -1.5342718 0.3597881 -4.264 2.00e-05 ***
## contra -0.6159529 0.2794023 -2.205 0.027487 *
## messi -1.0080507 0.2352887 -4.284 1.83e-05 ***
## ramos -0.9139156 0.2822291 -3.238 0.001203 **
## bale 0.7692322 0.1847618 4.163 3.14e-05 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## (Dispersion parameter for binomial family taken to be 1)
##
## Null deviance: 9000.5 on 6774 degrees of freedom
## Residual deviance: 8116.0 on 6715 degrees of freedom
## AIC: 8236
##
## Number of Fisher Scoring iterations: 4
La funció de summary ens dona una visió realment bona del model que acabem de construir. La secció de coeficients enumera totes les variables d’entrada utilitzades en el model.
Els arteriscs ens ofereixen la importància de cadascuna de les variables en termes estadístics. Així per exemple tenim que el terme “gracias” té un alt nivell significatiu i un valor positiu a la columna “Estimate”. Pel que és molt probable que un Tweet amb aquesta paraula sigui classificat com a positiu.
Ara utilitzarem el model per a una predicció en les dades de Validació. Utilitzarem type = “response” perquè els resultats de la predicció siguin probabilitats i el llindar de 0.5 per classificar la resposta com com a negativa (<0.5) o positiva (> 0.5).
## [1] 0.6749336
Veiem que amb el model de regressió logística obtenim una precisió bastant millor que l’obtinguda pel model base.
Ara per comprovar les prediccions realitzades sobre Tweets utilitzats farem servir el nostre model per etiquetar els Tweets i després obtenir una mostra aleatòria de 5 Tweets classificats com a positius.
## [1] "Vamos a por el viernes (@ Ayuntamiento de Málaga) [pic]: http://t.co/lzDVsoCu"
## [2] "Ya esta aquí. Ya llegó por fin la quinta ensaladera. Gracias a todos los miembros del equipo hoy mucha gente dormirá feliz."
## [3] "Una lástima lo de hoy pero esto no termina acá. En el fútbol siempre hay revancha y tenemos equipo para pelear por grandes cosas"
## [4] "Gracias ;) RT @sanzchile: *7714 México ;) RT: @AlejandroSanz: Voten por @Oscarcruzvm hay que (cont) http://t.co/pCXYPmr5"
## [5] "De nuevo Ai Weiwei luchando por la democracia en China http://t.co/VzDM6QYg"
A continuació una mostra aleatòria de 5 Tweets classificats com a negatius:
## [1] "Open Master Class@javiersolana &Pedro Alonso on \"Global Health Challenges&Global Governance\"@esadegeo@ISGLOBALorg http://t.co/UzhGWbiB… ."
## [2] "El desempleo en EE UU baja a los niveles de marzo de 2009 http://t.co/2RKKqQFG"
## [3] "@SSantiagosegura @angyfdz @flofdez BORRADO ESTÁ AMIGUETES!! UN ABRUZO!!;)"
## [4] "RT@FranHervias:UPyD pacta con Cascos para tener grupo.A pesar d que en 2008 decían que no era lícito este tipo d pactos http://t.co/fG5cVwM9"
## [5] "Palmas por sevillanas para animar a Rafa!! #sevillaciudadtalisman #copadavis"
Calculem ara els coeficients de la regressió logística, és a dir els efectes marginals, per saber la influència de cada variable independent en el resultat de la variable dependent. És a dir, com canvien les probabilitats que un Tweet sigui positiu a causa del canvi d’una unitat en les variables independents.
Quan els models impliquen una transformació no lineal, els coeficients generalment no són interpretables directament. Això es deu al fet que els coeficients expressen la influència de cada variable separada sobre la variable dependent en l’escala lineal del resultat, no l’escala discreta (o probabilitat) del resultat. Per exemple, en una regressió logística, els coeficients expressen l’efecte marginal de cada variable inclosa en termes del canvi en les probabilitats que l’esdeveniment sigui igual a 1 donat el canvi d’una unitat en la variable independent.
Per tal d’expressar el canvi d’una manera més intuïtiva en la probabilitat predita que el resultat és igual a 1, es requereix condicionar totes les altres variables incloses (és a dir, seleccionar un conjunt de valors per a totes les variables independents) i executar aquest conjunt de valors a través de la funció de logit per convertir els valors en probabilitats fent així que l’efecte marginal (en termes de probabilitat) d’una variable sigui una funció de totes les altres variables incloses en el model.
En realitat l’efecte marginal d’una variable donada és la pendent de la superfície de regressió respecte a una altra variable i ens indica la velocitat a la qual la variable dependent canvia en un punt donat, amb respecte a una dimensió concreta i mantenint constants tots els valors de les variables.
És un valor particularment útil perquè és intuïtiu, és simplement una pendent, i perquè pot ser calculat a partir d’essencialment qualsevol conjunt d’estimacions de regressió.
## factor AME SE z p lower upper
## ahora -0.0636 0.0338 -1.8839 0.0596 -0.1298 0.0026
## año 0.0693 0.0433 1.6003 0.1095 -0.0156 0.1541
## años 0.0452 0.0463 0.9767 0.3287 -0.0455 0.1360
## aquí 0.1126 0.0462 2.4397 0.0147 0.0221 0.2031
## así 0.0150 0.0459 0.3270 0.7437 -0.0750 0.1050
## bale 0.1586 0.0379 4.1831 0.0000 0.0843 0.2329
## barça -0.1133 0.0434 -2.6126 0.0090 -0.1983 -0.0283
## barcelona -0.2204 0.0529 -4.1662 0.0000 -0.3241 -0.1167
## bien 0.1956 0.0391 5.0002 0.0000 0.1190 0.2723
## bueno 0.1647 0.0423 3.8963 0.0001 0.0818 0.2475
## buenos 0.1841 0.0556 3.3088 0.0009 0.0750 0.2931
## congreso 0.0260 0.0495 0.5244 0.6000 -0.0711 0.1230
## contra -0.1270 0.0575 -2.2070 0.0273 -0.2398 -0.0142
## copa 0.0171 0.0423 0.4030 0.6870 -0.0659 0.1000
## cosas -0.1031 0.0606 -1.7018 0.0888 -0.2219 0.0156
## día 0.0950 0.0340 2.7917 0.0052 0.0283 0.1616
## días -0.0138 0.0487 -0.2834 0.7769 -0.1094 0.0817
## dice -0.1608 0.0521 -3.0864 0.0020 -0.2629 -0.0587
## dos -0.0001 0.0470 -0.0025 0.9980 -0.0923 0.0921
## equipo 0.2427 0.0577 4.2079 0.0000 0.1297 0.3558
## españa -0.0148 0.0376 -0.3943 0.6933 -0.0885 0.0589
## feliz 0.3988 0.0717 5.5621 0.0000 0.2583 0.5394
## final -0.0650 0.0527 -1.2334 0.2174 -0.1682 0.0383
## gobierno -0.0128 0.0360 -0.3553 0.7224 -0.0834 0.0578
## gracias 0.4754 0.0380 12.5251 0.0000 0.4010 0.5498
## gran 0.2328 0.0406 5.7341 0.0000 0.1532 0.3124
## grande 0.3639 0.0600 6.0703 0.0000 0.2464 0.4815
## hace -0.0524 0.0443 -1.1822 0.2371 -0.1393 0.0345
## hacer -0.0348 0.0454 -0.7661 0.4436 -0.1237 0.0542
## hoy 0.0535 0.0251 2.1351 0.0328 0.0044 0.1027
## madrid 0.1528 0.0250 6.1207 0.0000 0.1038 0.2017
## mañana 0.0430 0.0352 1.2231 0.2213 -0.0259 0.1120
## mas 0.0966 0.0348 2.7792 0.0055 0.0285 0.1648
## mejor 0.2851 0.0383 7.4386 0.0000 0.2100 0.3602
## menos 0.0143 0.0442 0.3238 0.7461 -0.0724 0.1010
## messi -0.2078 0.0483 -4.3021 0.0000 -0.3025 -0.1132
## mundo 0.0171 0.0586 0.2923 0.7701 -0.0977 0.1319
## nada -0.0407 0.0443 -0.9187 0.3582 -0.1276 0.0462
## noche 0.0287 0.0471 0.6102 0.5417 -0.0636 0.1210
## nuevo 0.1611 0.0493 3.2682 0.0011 0.0645 0.2577
## partido 0.0582 0.0411 1.4146 0.1572 -0.0224 0.1388
## portada -0.3163 0.0739 -4.2789 0.0000 -0.4612 -0.1714
## psoe -0.1387 0.0497 -2.7884 0.0053 -0.2361 -0.0412
## puede -0.0990 0.0516 -1.9196 0.0549 -0.2000 0.0021
## pues -0.0439 0.0517 -0.8497 0.3955 -0.1453 0.0574
## rajoy -0.0818 0.0361 -2.2637 0.0236 -0.1526 -0.0110
## ramos -0.1884 0.0580 -3.2460 0.0012 -0.3022 -0.0747
## real -0.0090 0.0390 -0.2298 0.8183 -0.0854 0.0675
## rey 0.0645 0.0499 1.2917 0.1965 -0.0334 0.1624
## rubalcaba 0.0028 0.0535 0.0519 0.9586 -0.1020 0.1076
## ser 0.0551 0.0382 1.4432 0.1490 -0.0197 0.1299
## siempre 0.1441 0.0471 3.0586 0.0022 0.0518 0.2364
## sin -0.1262 0.0385 -3.2804 0.0010 -0.2017 -0.0508
## solo -0.0370 0.0459 -0.8052 0.4207 -0.1270 0.0531
## tan -0.0665 0.0505 -1.3180 0.1875 -0.1655 0.0324
## vamos 0.1765 0.0429 4.1179 0.0000 0.0925 0.2605
## ver 0.0617 0.0363 1.6989 0.0893 -0.0095 0.1330
## vez -0.0649 0.0524 -1.2384 0.2156 -0.1676 0.0378
## vía -0.0017 0.0423 -0.0397 0.9683 -0.0845 0.0812
Podem comprovar com paraules com “gracias”, “grande” o “mejor” tenen un efecte marginal mitjana (AME) gran pel que la seva presència influeix en què un Tweet sigui classificat com Positiu. En canvi paraules com “contra” o “sin” influeixen en què un Tweet sigui classificat com no Positiu.
A continuació il·lustrarem com influeix la combinació de les paraules “gracias” i “grande” en la predicció d’un Tweet Positiu:
##
## # Predicted probabilities of Positivo
## # x = gracias
##
## # 0
## x predicted std.error conf.low conf.high
## 0 0.352 0.028 0.340 0.365
## 1 0.845 0.189 0.790 0.888
## 2 0.982 0.379 0.963 0.991
## 3 0.998 0.570 0.994 0.999
##
## # 1
## x predicted std.error conf.low conf.high
## 0 0.761 0.292 0.642 0.849
## 1 0.970 0.348 0.942 0.984
## 2 0.997 0.480 0.992 0.999
## 3 1.000 0.642 0.999 1.000
##
## # 2
## x predicted std.error conf.low conf.high
## 0 0.949 0.585 0.855 0.983
## 1 0.995 0.616 0.982 0.998
## 2 0.999 0.699 0.998 1.000
## 3 1.000 0.820 1.000 1.000
##
## Adjusted for:
## * día = 0.02
## * menos = 0.02
## * hoy = 0.05
## * madrid = 0.06
## * ser = 0.02
## * congreso = 0.01
## * días = 0.02
## * gran = 0.02
## * ahora = 0.03
## * mundo = 0.01
## * sin = 0.03
## * puede = 0.01
## * siempre = 0.01
## * copa = 0.03
## * españa = 0.02
## * ver = 0.02
## * noche = 0.01
## * dos = 0.01
## * hace = 0.02
## * así = 0.01
## * nuevo = 0.01
## * vía = 0.02
## * años = 0.01
## * nada = 0.02
## * vez = 0.01
## * bien = 0.02
## * bueno = 0.01
## * tan = 0.01
## * buenos = 0.02
## * gobierno = 0.02
## * solo = 0.02
## * rajoy = 0.03
## * final = 0.01
## * mas = 0.02
## * mejor = 0.02
## * rey = 0.02
## * vamos = 0.01
## * equipo = 0.01
## * partido = 0.02
## * año = 0.01
## * pues = 0.01
## * cosas = 0.01
## * feliz = 0.01
## * barcelona = 0.02
## * real = 0.02
## * barça = 0.02
## * rubalcaba = 0.01
## * aquí = 0.01
## * psoe = 0.02
## * mañana = 0.02
## * dice = 0.02
## * hacer = 0.02
## * portada = 0.01
## * contra = 0.01
## * messi = 0.02
## * ramos = 0.02
## * bale = 0.02
I com influeix la combinació de les paraules “contra” i “sense” en la predicció d’un Tweet Negatiu:
##
## # Predicted probabilities of Positivo
## # x = contra
##
## # 0
## x predicted std.error conf.low conf.high
## 0 0.384 0.028 0.371 0.397
## 1 0.252 0.278 0.163 0.367
## 2 0.154 0.557 0.057 0.351
##
## # 1
## x predicted std.error conf.low conf.high
## 0 0.252 0.186 0.190 0.327
## 1 0.154 0.333 0.087 0.259
## 2 0.090 0.586 0.030 0.237
##
## # 2
## x predicted std.error conf.low conf.high
## 0 0.155 0.372 0.081 0.275
## 1 0.090 0.463 0.038 0.197
## 2 0.051 0.668 0.014 0.165
##
## # 3
## x predicted std.error conf.low conf.high
## 0 0.090 0.558 0.032 0.229
## 1 0.051 0.623 0.016 0.154
## 2 0.028 0.787 0.006 0.119
##
## # 4
## x predicted std.error conf.low conf.high
## 0 0.051 0.745 0.012 0.188
## 1 0.028 0.794 0.006 0.121
## 2 0.015 0.929 0.003 0.088
##
## Adjusted for:
## * día = 0.02
## * gracias = 0.04
## * menos = 0.02
## * hoy = 0.05
## * madrid = 0.06
## * grande = 0.01
## * ser = 0.02
## * congreso = 0.01
## * días = 0.02
## * gran = 0.02
## * ahora = 0.03
## * mundo = 0.01
## * puede = 0.01
## * siempre = 0.01
## * copa = 0.03
## * españa = 0.02
## * ver = 0.02
## * noche = 0.01
## * dos = 0.01
## * hace = 0.02
## * así = 0.01
## * nuevo = 0.01
## * vía = 0.02
## * años = 0.01
## * nada = 0.02
## * vez = 0.01
## * bien = 0.02
## * bueno = 0.01
## * tan = 0.01
## * buenos = 0.02
## * gobierno = 0.02
## * solo = 0.02
## * rajoy = 0.03
## * final = 0.01
## * mas = 0.02
## * mejor = 0.02
## * rey = 0.02
## * vamos = 0.01
## * equipo = 0.01
## * partido = 0.02
## * año = 0.01
## * pues = 0.01
## * cosas = 0.01
## * feliz = 0.01
## * barcelona = 0.02
## * real = 0.02
## * barça = 0.02
## * rubalcaba = 0.01
## * aquí = 0.01
## * psoe = 0.02
## * mañana = 0.02
## * dice = 0.02
## * hacer = 0.02
## * portada = 0.01
## * messi = 0.02
## * ramos = 0.02
## * bale = 0.02
A partir del teorema de Bayes, LDA estima la probabilitat que una observació, donat un determinat valor de les variables independents, pertanyi a una de les classes de la variable qualitativa, P (I = k | X = x). Un cop obtinguda la proabilidad i per realitzar la classificació s’assigna l’observació a la classe k per la qual la probabilitat predita és més gran.
## LD1
## día 0.664754446
## gracias 2.544478910
## menos 0.113407694
## hoy 0.354617911
## madrid 1.013783726
## grande 2.050711967
## ser 0.343875310
## congreso 0.145191385
## días -0.072714288
## gran 1.488400037
## ahora -0.397779584
## mundo 0.059939255
## sin -0.694346379
## puede -0.635106813
## siempre 0.821424622
## copa 0.115818662
## españa -0.111321212
## ver 0.387978812
## noche 0.133854015
## dos 0.016689710
## hace -0.335136426
## así 0.116561580
## nuevo 1.051328491
## vía -0.035899615
## años 0.293411185
## nada -0.261282957
## vez -0.395191127
## bien 1.279603619
## bueno 1.145744815
## tan -0.452328720
## buenos 1.271221719
## gobierno -0.094866588
## solo -0.243929587
## rajoy -0.505452937
## final -0.373058993
## mas 0.636680255
## mejor 1.782001497
## rey 0.419783065
## vamos 1.214818149
## equipo 1.430379004
## partido 0.397574893
## año 0.377025232
## pues -0.266543074
## cosas -0.623905905
## feliz 2.280061300
## barcelona -1.207934129
## real -0.071301920
## barça -0.657438290
## rubalcaba -0.001741248
## aquí 0.709184599
## psoe -0.809361474
## mañana 0.287791652
## dice -0.883922833
## hacer -0.225172413
## portada -1.571297628
## contra -0.761582348
## messi -1.113180589
## ramos -1.094742067
## bale 0.715900476
Quan representam els coeficients de la funció discriminant lineal veiem hi ha una zona que es solapa. Aquesta és la zona que incrementarà el valor de les taxes d’error de classificació del model.
La predicció que s’obté sobre el conjunt de validació és la següent:
## [1] 0.6740478
Veiem com és lleugerament superior a l’obtinguda per Logit.
L’anàlisi disciminante quadràtic considera que cada classe k té la seva pròpia matriu de covariança i, com a conseqüència, la funció discriminant pren forma quadràtica. A causa d’això genera límits de decisió corbs pel que pot aplicar-se a situacions en què la separació entre grups no és lineal.
## Call:
## qda(Positivo ~ ., data = train_data_words_df)
##
## Prior probabilities of groups:
## FALSE TRUE
## 0.619631 0.380369
##
## Group means:
## día gracias menos hoy madrid grande
## FALSE 0.01715102 0.007860886 0.01595998 0.04311577 0.04097189 0.003811339
## TRUE 0.03337214 0.091191308 0.01435778 0.05781917 0.08963912 0.025611176
## ser congreso días gran ahora mundo
## FALSE 0.01858028 0.01333969 0.01667461 0.009528347 0.03358742 0.008575512
## TRUE 0.02483508 0.01125340 0.02444703 0.032984090 0.02367094 0.015133877
## sin puede siempre copa españa ver
## FALSE 0.03096713 0.01476894 0.009051929 0.03454026 0.02310624 0.02024774
## TRUE 0.01590997 0.01008925 0.023670935 0.03531238 0.02017850 0.02522313
## noche dos hace así nuevo vía
## FALSE 0.01071939 0.01310148 0.01715102 0.01191043 0.008099095 0.01786565
## TRUE 0.01668607 0.01164144 0.01552192 0.01590997 0.018238262 0.01513388
## años nada vez bien bueno tan
## FALSE 0.01333969 0.01762744 0.013816103 0.01167222 0.01000476 0.01262506
## TRUE 0.01435778 0.01396973 0.009313155 0.03065580 0.02289484 0.01280559
## buenos gobierno solo rajoy final mas
## FALSE 0.01000476 0.02596475 0.01595998 0.03358742 0.01214864 0.01810386
## TRUE 0.02405898 0.02017850 0.01396973 0.01862631 0.01047730 0.03065580
## mejor rey vamos equipo partido año
## FALSE 0.01048118 0.01643640 0.01024297 0.005002382 0.01405431 0.01238685
## TRUE 0.04850601 0.02483508 0.02173069 0.021342646 0.01862631 0.01785021
## pues cosas feliz barcelona real barça
## FALSE 0.01262506 0.011195808 0.002382087 0.019056694 0.01572177 0.01977132
## TRUE 0.01086535 0.007372914 0.023670935 0.008925107 0.03531238 0.01474583
## rubalcaba aquí psoe mañana dice hacer
## FALSE 0.012625060 0.01071939 0.020962363 0.02024774 0.021676989 0.01667461
## TRUE 0.008925107 0.01862631 0.009313155 0.02483508 0.007760962 0.01280559
## portada contra messi ramos bale
## FALSE 0.017389233 0.014530729 0.024535493 0.019771320 0.01214864
## TRUE 0.003492433 0.006596818 0.009313155 0.008925107 0.03531238
El valor de predicció de QDA en el conjunt de validació és el següent:
## [1] 0.6572188
Veiem que el valor obtingut és inferior a l’obtingut en models anteriors.
En el model dels arbres de classificació a cada pas s’avaluen totes les variables d’entrada i tots els punts de divisió possibles i es tria la que tingui millor resultat. És a dir, dividim les dades en dos o més conjunts homogenis basats en la variable més significativa.
És molt probable que aquest model no funcioni correctament per les nostres dades ja que els models basats en arbres no estan dissenyats per funcionar amb característiques molt disperses i tal com hem pogut veure en l’apartat d’anàlisi d’informació, les nostres dades tenen valors de sparsity molt elevats.
Si entrenem un model amb el model d’arbres de decisió veiem com només ens dectecta 2 nodes terminals sent el terme “gràcias” determinant per predir si un Tweet és Positiu o no. És un indicador que la variable “gracies” classifica gairebé perfectament a les nostres mostres i encara que sembla correcte, a causa de la limitació d’aquest model i a la naturalesa de les nostres dades, això no ens permet contemplar altres possibilitats de combinacions de termes, de manera que no podria servir-nos per exemple per classificar un Tweet que no tingui la paraula “gracias” ja que sempre obtindríem com a resultat que el Tweet és negatiu.
Per realitzar la predicció, el model recorre l’arbre en funció del valor de les seves variables fins a arribar a un dels nodes terminals. En el cas de classificació, sol emprar-se la classe més freqüent del node per decidir quina variable escollir.
## [1] 0.6466421
Per comprovar si es genera overfitting, farem una predicció sobre el conjunt de dades d’entrenament. Veiem com el resultat obtingut no és molt alt. Fet que ens indica que el model no genera overfitting sobre les dades d’Training. Fem ara la predicció sobre les dades de Validació.
## [1] 0.6390611
Efectivament, obtenim un valor molt semblant a l’obtingut amb les dades de Training (No overfitting) però és dels més baixos obtinguts fins ara amb tots els models aplicats. La limitació d’aquest model és que només es genera un únic arbre i per tant només és capaç de comprovar una combinació de probabilitats que en el nostre cas resulta ser molt limitada.
Hem comprovat com el model no genera overfitting i com per tant, no és necessari realitzar cap tipus de limitació de la mida de l’arbre o poda, però volem generar un model que pugui servir-nos per a altres conjunts de dades als utilitzats en aquesta comparativa pel que realitzarem els procediments habituals per obtenir els paràmetres més òptims d’aquest model.
La mida final pot controlar-se mitjançant regles per la divisió dels nodes depenent de si es compleixen o no determinades condicions. Són les següents:
Observacions mínimes per divisió: defineix el nombre mínim d’observacions que ha de tenir un node per poder ser dividit. Com més gran el valor, menys flexible és el model.
Observacions mínimes de node terminal: defineix el nombre mínim d’observacions que han de tenir els nodes terminals. El seu efecte és molt similar al d’observacions mínimes per divisió.
Profunditat màxima de l’arbre: defineix la profunditat màxima de l’arbre, entenent per profunditat màxima el nombre de divisions de la branca més llarga (en sentit descendent) de l’arbre.
Nombre màxim de nodes terminals: defineix el nombre màxim de nodes terminals que pot tenir l’arbre. Un cop assolit el límit, s’aturen les divisions. El seu efecte és similar al de controlar la profunditat màxima de l’arbre.
Reducció mínima d’error: defineix la reducció mínima d’error que ha d’aconseguir una divisió perquè es dugui a terme.
Tots aquests paràmetres són el que es coneix com hiperparàmetres perquè no s’aprenen durant l’entrenament del model. El seu valor ha de ser especificat per l’usuari en base al seu coneixement del problema i mitjançant l’ús de validació creuada.
Tot i que no tingui sentit per al nostre cas, vam realitzar Validació Creuada per podar i obtenir la mida de l’arbre amb menor error de classificació
## $size
## [1] 2 1
##
## $dev
## [1] 2382 2577
##
## $k
## [1] -Inf 183
##
## $method
## [1] "misclass"
##
## attr(,"class")
## [1] "prune" "tree.sequence"
## [1] 2
Efectivament l’arbre amb menor error de classificació té dos nodes terminals.
Realitzem el procés de Poda indicant el paràmetre best obtingut a la funció prune.misclass
I òbviament obtenim el mateix arbre.
Veurem a continuació com afecta el procés de poda als valors de predicció sobre Training i Validació per comprovar l’overfitting. (En el nostre cas no variaran dels valors obtinguts anteriorment.)
Per a Training:
## [1] 0.6466421
Per a Validació:
## [1] 0.6390611
Veiem com obtenim els mateixos valors que els obtinguts anteriorment però la realització del procés complet ens permet canviar el nostre conjunt de dades original i disposar de tota la lògica necessària per analitzar aquest model completament.
El model dels arbres de classificació pateix també el problema de l’equilibri entre biaix i variànça. Per solucionar-ho i trobar el millor equilibri utilitzarem els models de Bagging i Boosting.
A Bagging en lloc de crear un model d’un únic arbre s’ajusten molts models amb diferents mostres (obtingudes a través d ’ Bootstrapping ) de manera paral·lela formant un “bosc” de tal manera que tots els arbres participen en la realització d’una predicció i com a valor final es té en compte la classe més freqüent. D’aquesta manera es fan servir models amb poc biaix però molta variànça, però afegint molts d’aquests models s’aconsegueix reduir la variànça.
A Bagging la forma d’obtenir les mostres a través de Bootstrapping permet que es pugui estimar l’error directament a través del “Out Of Bag” (OOB) format per una mitjana d’un terç de les mostres emprades. Aquest terç que Bootstrapping no ha utilitzat per a la selecció d’observacions pot utilitzar-se per realitzar la predicció i en el nostre cas obtenir el “OOB-classification-error”.
A continuació entrenem el model de Bagging amb les nostres dades de Training.
##
## Call:
## randomForest(formula = Positivo ~ ., data = train_data_words_df)
## Type of random forest: classification
## Number of trees: 500
## No. of variables tried at each split: 7
##
## OOB estimate of error rate: 32.19%
## Confusion matrix:
## FALSE TRUE class.error
## FALSE 3766 432 0.1029061
## TRUE 1749 828 0.6786962
Anem a comprovar si hi ha “overfitting”. Per això realitzarem la predicció sobre les dades d’Training.
## [1] 0.7138007
Comprovam com la precisió en el model de classificació és molt alta, pel que es tracta d’un indicador d’“overfitting”.
Fem ara la predicció en el conjunt de Validació.
## [1] 0.6780337
Veiem com amb el model de Bagging obtenim una bona precisió de classificació. La guardem per poder comparar-la amb tots els models.
Es tracta d’un dels mètodes de Bagging més coneguts. Té en compte la correlació que hi pot haver entre els múltiples arbres generats ja que si la correlació entre ells és alta no es podrà aconseguir reduir la variança d’una manera notable. Per solucionar aquest problema Random Forest realitza una selecció aleatòria de m predictors abans d’avaluar cada divisió dels arbres per evitar que els predictors influents puguin ser seleccionats i així que la correlació entre els arbres generats sigui alta.
Tant Bagging com Random Forest segueixen les mateixes passes però Random Forest realitza un pas addicional de selecció de predictors abans de cada divisió. Es pot dir que Bagging és una generalització de Random Forest per m = p. Aquest fet ens indica que haurem de triar un m òptim.
Vegem a continuació l’evolució del OOB-Error en funció del paràmetre m per escollir l’òptim. També realitzarem una gràfica comparativa entre el Test-Error i el OOB-Error.
## # A tibble: 1 x 2
## n_predictores oob_err_rate
## <int> <dbl>
## 1 6 0.327
Obtenim que 6 és el nombre de predictors òptim a utilitzar. Farem servir aquest valor per optimitzar la mida dels nodes terminals.
## # A tibble: 20 x 2
## size oob_err_rate
## <int> <dbl>
## 1 18 0.320
## 2 16 0.321
## 3 11 0.321
## 4 6 0.321
## 5 7 0.321
## 6 9 0.321
## 7 20 0.321
## 8 17 0.321
## 9 13 0.321
## 10 10 0.322
## 11 12 0.322
## 12 3 0.322
## 13 19 0.322
## 14 2 0.323
## 15 14 0.323
## 16 1 0.323
## 17 15 0.324
## 18 8 0.324
## 19 4 0.325
## 20 5 0.325
## # A tibble: 1 x 2
## size oob_err_rate
## <int> <dbl>
## 1 18 0.320
Obtenim que el nombre òptim d’observacions mínimes dels nodes terminals és 18.
Un cop obtinguts aquests paràmetres els utilitzem per obtenir el nombre d’arbres òptim.
## oob_err arboles
## 1 0.3194096 92
Obtenim que el nombre d’arbres òptim és de 92.
Utilitzant tots els paràmetres obtinguts generem el model final.
##
## Call:
## randomForest(formula = Positivo ~ ., data = train_data_words_df, mtry = 6, ntree = 92, nodesize = 18, importance = TRUE, norm.votes = TRUE)
## Type of random forest: classification
## Number of trees: 92
## No. of variables tried at each split: 6
##
## OOB estimate of error rate: 32.47%
## Confusion matrix:
## FALSE TRUE class.error
## FALSE 3771 427 0.1017151
## TRUE 1773 804 0.6880093
Anem a fer ara la predicció sobre el conjunt de validació utilitzant el model obtingut a partir dels paràmetres òptims.
## [1] 0.6789194
Guardarem el valor per comparar-lo amb els altres models.
Un cop obtingut el model òptim per al model de Random Forest, vegem quines són les variables més influents del model i com afecten a la precisió obtinguda.
Observem que les variables formades pels termes “gracias”, “feliz”, “grande”, “mejor” són de les més influents i com la paraula “gracias” destaca sobre de totes les altres. Recordem que aquest fet ja va ser detectat clarament amb el model d’“Arbres de Classificació”.
Ens demanem ara què passaria si el nostre model només depengués d’aquestes variables més influents.
##
## Call:
## randomForest(formula = Positivo ~ +gracias + feliz + grande + mejor, data = train_data_words_df, mtry = 6, ntree = 92, nodesize = 18, importance = TRUE, norm.votes = TRUE)
## Type of random forest: classification
## Number of trees: 92
## No. of variables tried at each split: 4
##
## OOB estimate of error rate: 33.21%
## Confusion matrix:
## FALSE TRUE class.error
## FALSE 4097 101 0.02405908
## TRUE 2149 428 0.83391541
Veiem que obtenim un percentatge d’error més gran que utilitzant totes les variables. Atès que volem aconseguir uns valors òptims optarem per utilitzar totes les variables.
Boosting és com hem indicat anteriorment un altre dels mètodes utilitzats per poder trobar el millor equilibri entre biaix i variança.
Aquest model consisteix a ajustar molts models senzills de manera seqüencial i que cada un d’ells tingui en compte els errors de l’anterior. El valor final s’obté considerant la classe més freqüent, de la mateixa manera que en Bagging. D’aquesta manera els models que s’empren a Boosting tenen molt poca variança però molt biaix i considerant molts d’aquests models s’aconsegueix reduir el biaix.
Utilitzem el paquet “caret” amb un tuneGrid o graella de diferents valors i “Validació Creuada”" per trobar els següents paràmetres òptims:
interaction.depth: és el nombre de divisions que té l’arbre. El rang de valors que utilitzarem serà: 1, 5 i 10
n.trees: es tracta del nombre de models que es generen. En augmentar aquest valor reduïm l’error d’entrenament però generam “overfitting”. Els valors que utilitzarem per al nostre grid seran: 50, 100, 200
shrinkage: és el learning rate i atès que a Boosting els models depenen dels valors anteriors, controla la influència de cada un d’ells sobre el total. La idea en referència a aquest paràmetre és optar per valors petits ja que és preferible un model amb molts passos, però cada un d’ells amb una menor influència que un model amb pocs passos. Els valors utilitzats són: 0.005, 0.05, 0.5
n.minobsinnode: és el nombre d’observacions mínim perquè un node pugui ser dividit. Els valors utilitzats són: 1, 10, 20
Obtenim que la millor combinació de paràmetres és la següent:
## n.trees interaction.depth shrinkage n.minobsinnode
## 45 200 5 0.05 20
El millor valor de precisió obtingut a través de Validació Creuada és el següent:
## [1] 0.6823617
Si fem la predicció sobre el conjunt de validació obtenim el següent valor:
## [1] 0.6753764
Guardarem aquest valor per poder comparar-lo.
XGBoost és una de les implementacions del concepte Gradient Boosting i utilitza la mateixa filosofia de classificadors febles que aporten la informació dels errors als models posteriors. Però el que fa que XGBoost sigui únic és que utilitza una formalització de model més regularitzada per controlar l’“overfitting”, el que li dóna un millor rendiment. La implementació de XGBoost ofereix diverses característiques avançades per a l’ajust de models i admet un ajust detallat i l’addició de paràmetres de regularització.
Per aplicar el model de “Extreme Gradient Boosting” utilitzarem el paquet “caret” i mitjançant TuneGrid i TrainControl de Validació Creuada de 5 folds ajustarem els següents paràmetres:
nrounds : El nombre màxim d’iteracions (nombre d’arbres al model final). Els valors utilitzats són 100 i 350.
colsample_bytree : El nombre de característiques, expressades com una proporció, a mostrejar quan es construeix un arbre. És el nombre de variables aleatòries que se li proporciona a cada nou arbre. El valor per omissió és 1 (100% de les característiques). El valor que utilitzarem és de 0.75.
min_child_weight : El pes mínim en els arbres que estan sent generats. El valor per defecte és 1. Els valors que utilitzem són 0, 0.5 i 1
eta : Taxa d’aprenentatge, que és la contribució de cada arbre a la solució. El valor per omissió és 0.3. Els valors que hem utilitzat són 0.05, 0.1 i 0.5.
gamma : Reducció de pèrdua mínima requerida per fer una altra partició en un arbre. Utilitzem 0.01 com a valor en el nostre Grid.
subsample : Relació d’observacions de dades. El valor per omissió és 1 (100%). Utilitzarem 0.5.
max_depth : Màxima profunditat dels arbres individuals. Utilitzarem els valors 4, 6 i 10.
## + Fold1: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold1: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold1: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold2: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold2: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold3: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold3: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold4: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold4: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.05, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.05, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.05, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.10, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.10, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.10, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.50, max_depth= 4, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.50, max_depth= 6, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## + Fold5: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## - Fold5: eta=0.50, max_depth=10, gamma=0.01, colsample_bytree=0.75, min_child_weight=0, subsample=0.5, nrounds=350
## Aggregating results
## Selecting tuning parameters
## Fitting nrounds = 100, max_depth = 4, eta = 0.05, gamma = 0.01, colsample_bytree = 0.75, min_child_weight = 0, subsample = 0.5 on full training set
A continuació obtindrem el model final que amb els paràmetres indicats ofereix millors resultats.
## ##### xgb.Booster
## raw: 94.3 Kb
## call:
## xgboost::xgb.train(params = list(eta = param$eta, max_depth = param$max_depth,
## gamma = param$gamma, colsample_bytree = param$colsample_bytree,
## min_child_weight = param$min_child_weight, subsample = param$subsample),
## data = x, nrounds = param$nrounds, verbose = FALSE, objective = "binary:logistic")
## params (as set within xgb.train):
## eta = "0.05", max_depth = "4", gamma = "0.01", colsample_bytree = "0.75", min_child_weight = "0", subsample = "0.5", objective = "binary:logistic", silent = "1"
## xgb.attributes:
## niter
## # of features: 60
## niter: 100
## nfeatures : 60
## xNames : Positivo día gracias menos hoy madrid grande ser congreso días gran ahora mundo sin puede siempre copa españa ver noche dos hace así nuevo vía años nada vez bien bueno tan buenos gobierno solo rajoy final mas mejor rey vamos equipo partido año pues cosas feliz barcelona real barça rubalcaba aquí psoe mañana dice hacer portada contra messi ramos bale
## problemType : Classification
## tuneValue :
## nrounds max_depth eta gamma colsample_bytree min_child_weight subsample
## 1 100 4 0.05 0.01 0.75 0 0.5
## obsLevels : No Yes
## param :
## $verbose
## [1] FALSE
Realitzem la predicció sobre el conjunt de validació.
## [1] 0.6651904
Veiem com tot i la potència d’aquest algoritme sembla que no obtenim el valor més alt de precisió. Guardarem el valor per comparar-lo amb els altres models
Un altre mètode per mesurar el rendiment en la classificació binària a més de la precisió és el mètode ROC. A diferència de la precisió, l’anàlisi ROC utilitza la taxa de veritables positius (TPR) i la taxa de falsos positius (FPR). TPR és la proporció positiva classificada correctament (TP / P) i la taxa de falsos positius (FPR) es calcula per 1-TNR (TN / N). La regió ROC mostra la taxa de veritables postius (TPR) contra la taxa de falsos positius (FPR).
## Model Area p.value binorm.area
## 1 Model 1 0.6253007 2.059215e-27 NA
Com podem veure el model pot diferenciar entre Tweets Positius i no Positius però si ens fixem en el Àrea Under Curve (AUC) veiem que el valor obtingut és proper al 65%.
El coeficient de GINI mesura la desigualtat entre els valors d’una distribució. Un coeficient de Gini de zero expressa una igualtat perfecta, d’altra banda, el coeficient de Gini d’1 (100%) expressa la màxima desigualtat entre els valors.
## [1] 0.270966
En el nostre cas veiem com el coeficient de GINI expressa una desigualtat de 27%. Hi ha una relació entre el coeficient de GINI i el AUC però atès que en aquesta pràctica ens hem centrat en la precisió (ACC) no utilitzarem aquests valors.
Il·lustrem a continuació la importància de les variables segons el model XGB. Veiem com el terme “gracias” destaca per sobre de les altres i com coincideixen en la gran majoria amb la importància vista en el model de Boosting.
“Support Vector Machine” (SVM) és un algoritme supervisat d’aprenentatge automàtic que s’utilitza principalment en problemes de classificació. Va ser desenvolupat en la dècada dels 90, dins del camp de la ciència computacional. Si bé es va desenvolupar de manera original com a mètode de classificació binària, la seva aplicació ha estat estesa a problemes de classificació múltiple i de regressió. Els algoritmes de SVM han resultat ser un dels millors classificadors per a un ampli ventall de situacions, pel que s’anomena un referent dins de l’àmbit d’aprenentatge estadístic i d’aprenentatge automàtic. En aquest algoritme, representem cada element de dades com a punt en un espai n-dimensional (on n és el nombre de característiques que tenim) i el valor de cada característica és el valor d’una coordenada particular. A continuació, es realitza la classificació trobant l’hiperplà que diferencia les diferents classes de la millor manera. Aquesta tasca es realitza maximitzant les distàncies entre els punts més propers de cada clase per aconseguir l’hiperplà òptim de separació.
És relativament fàcil obtenir un hiplerplà lineal entre dues clases però, què passa si la separació entre dues classes no és lineal? Per resoldre aquest problema SVM disposa de funcions de kernel que permeten transformar un espai no lineal i dificilment separable en un espai lineal i separable. Es disposa de diferents tipus de kernels per transformar la informació però en aquest TFM compararem el lineal i el radial.
En aquest algoritme és necessari convertir la variable depenent en categòrica. Recordem que fins el moment havíem treballat amb la variable “positivo” de manera qualitativa. A continuació, emprarem el paquet caret que permet definir una matriu de control per aplicar l’algoritme de SVM amb la tècnica de la “validació creuada”. En el nostre cas el mètode que emprarem serà “repeatedcv” amb un fold de tamany 10 i 3 repeticions. SVM disposa també d’un paràmetre de preProcess() que permet indicar com normalitzar les dades a tractar. En el nostre cas, el valor d’aquest paràmetre serà de “center, scale”, valors que indiquen que les nostres dades es convertiran per tenir una mitja 0 i una desviació estàndar de 1.
A continuació realitzarem la predicció.
## [1] 0.6979628
Veim com el valor obtingut és elevat comparat amb els altres algoritmes. Anem a veure ara si aquest valor es pot millorar. Per això el que farem serà emprar una graella de valors (tuneGrid) per trobar el valor de l’hiperparàmetre C òptim.
A continuació es pot observar la gràfica obtinguda per diferents valors de l’hiperparàmetre C. Veim com el valor òptim correspon a C=0.01
Emprarem el model amb aquest valor per realitzar la predicció.
## [1] 0.7037201
El valor obtingut és el més alt fins al moment. Però encara ens queda explorar la versió corresponent al kernel radial. Realitzarem el mateix procés que abans. Primer amb un trainControl basat en CV.
Un cop obtingut el model realitzam la predicció.
## [1] 0.6505757
El valor obtingut no és tan elevat com l’obtingut amb el kernel lineal. De fet, és dels més baixos.
Emprarem a continuació un tuneGrid per trobar els valors òptims dels hiperparàmetres “sigma” i “C” sent els òtims 0.001 i 0.5 respectivament.
La gràfica obtinguda ens indica els nivells de precisió obtinguts per diferents valors de “C” i “Sigma”
Finalment, realitzam la predicció amb el kernel radial al conjunt de validació.
## [1] 0.6695748
Veim com el resultat no millora molt del resultat obtingut anteriorment.
Un cop ja hem realitzat la generació dels models en el nostre conjunt de Training i les prediccions en el nostre conjunt de Validació, compararem els valors de precisió en la classificació dels diferents models estudiats.
## ACCURACY MODELS
## 1 0.6196634 BLINE
## 2 0.6749336 LOGREG
## 3 0.6740478 LDA
## 4 0.6572188 QDA
## 5 0.6390611 TREE
## 6 0.6390611 PRUNE
## 7 0.6780337 BAG
## 8 0.6789194 RF
## 9 0.6753764 GBM
## 10 0.6651904 XGB
## 11 0.6979628 SVM
## 12 0.7037201 SVM GR
## 13 0.6505757 SVM RADIAL
## 14 0.6695748 SVM RAD GR
Obtenim que el millor model és SVM amb un valor del 70,37%. És una millora molt considerable respecte l’error mínim de classificació.
A continuació aplicarem el millor model obtingut a un nou conjunt de Training format pels antics conjunts de Training i Validació i aplicarem la predicció a un conjunt de Test que els nostres models encara no han vist.
El nombre d’observacions dels nostres nous conjunts de Training i Test són els següents:
## [1] 9033 60
## [1] 2257 60
Podria passar que en ampliar el conjunt de dades dels valors òptims que hem calculat anteriorment per al model de SVM ja no fossin els mateixos. Per a això aplicarem Validació Creuada amb els mateixos rangs de valors que els aplicats anteriorment per obtenir la configuració òptima de paràmetres.
Obtenim que els paràmetres òptims són els següents:
## C
## 2 0.02
El millor valor de precisió obtingut a través de Validació Creuada en el nou conjunt de Training és el següent:
## [1] 0.6776651
Finalment, vam realitzar la predicció sobre el conjunt de test.
## [1] 0.6837
Tot i esser un valor elevat, obtenim un valor inferior a l’obtingut anteriorment.
En aquesta anàlis hem comparat un total de 9 models de classificació per obtenir el que ens proporcionés millors resultats de precisió sobre Tweets correctament classificats com a positius. Per a això hemo seguit els criteris de divisió del conjunt de dades en Training, Validació i Test i hem aplicat Validació Creuada per optimitzar els paràmetres dels models que ho requerien. En comparar tots els models el que millor resultats ha ofert ha estat SVM.
A continuació hem vist que per a un conjunt de dades de Training de 6.000 mostres el millor model ha obtingut una precisió d’un 70,37%, sent un valor molt acceptable. Però quan hem utilitzat les observacions reservades per Test el percentatge de classificació correcta ha baixat fins a un 68%.
A continuació identificarem possibles dificultats que fan que sigui molt difícil arribar a unes precisions més elevades:
Una mostra de Tweets petita i un coeficient de dispersió petit. Cal considerar que un total de 9.000 Tweets de Training per al model final és un valor relativament petit i que aplicant el coeficient de dispersió de l’1% només hem aconseguit un total de 1116 termes que són les variables independents que han de tenir el poder significatiu suficient com per classificar nous Tuits. Com hem d’esperar el poder significatiu d’aquests termes no és del tot suficient.
La complexitat de modelar el llenguatge natural. Un altre punt a considerar per donar una explicació al resultat de precisió és la complexitat del llenguatge natural. En aquesta pràctica només hem considerat els termes de manera independent però considerar unes característiques que poguessin contemplar el poder significatiu de la combinació de n-termes (n-grams) podria donar més significat a les variables i major influència a l’hora de predir la polaritat d’un Tweet. En aquest sentit, el tractament de les abreviacions, els emojis, la detecció d’ironies, l’anàlisi de la construcció sintàctica de les paraules, la consideració del valor semàntic dels termes que formen un Tweet o una contextualització dels missatges podria ajudar a obtenir millors resultats.
La subjectivitat de la classificació. És important destacar aquest aspecte ja que segons s’ha pogut comprovar revisant el text d’alguns Tweets, aquests han estat classificats d’una manera molt subjectiva i per exemple Tweets que parlessin del Reial Madrid o de Cristina Ronaldo eren classificats com Positius i d’altres que parlessin de Messi o el FC Barcelona eren considerats negatius. Aquests aspectes també han pogut influir en la correcta classificació dels nostres models.
De tota manera, cal indicar que segons les fonts consuladas ( ELiRF-UPV en TASS 2015: Análisis de Sentimientos en Twitter ) els percentatges més elevats que s’han obtingut utilitzant mostres grans i algoritmes més complexos com SVM han estat del 72%. Per tant ens hem acostat molt a aquests valors.
En qualsevol cas, hem desenvolupat la comparativa de diferents models predictius de classificació, l’estructura de la qual ens pot servir en futurs treballs per obtenir millors resultats aportant noves característiques com els n-grams que ajudin a obtenir major significació a les variables.